/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package javamail.web;

import javamail.web.util.eParseState;
import javamail.web.util.eParseRequest;
import javamail.web.util.eParseOption;
import java.util.StringTokenizer;

/**
 *
 * @author sriram
 */
public class httpParser {
    private eParseRequest request = eParseRequest.NIL;  // Request being parsed is set to NIL
    private eParseState state = eParseState.NIL;        // Parsing state, set to NIL in the beginning
    private eParseOption option = eParseOption.NIL;        // Option being parsed is set to NIL
    private String toParse = null;                      // String to be parsed

    private String fileName = null;
    private String[] optVal;                            // Array that stores the options in the request
    private String request_parms = null;                   // POST parameters
    
    public httpParser() {
        optVal = new String[option.MAXOPT.toInt()];
    }
    
    public boolean setParseString(String parse) {
        if(parse != null) {
            if (toParse != null)
                toParse = parse;
            else
                toParse = new String(parse);
        }
        else {
            return false;
        }
        return true;
    }
    
    public boolean parseLine(String parse) {
        boolean result = false;
        // Set the state to Request if still NIL
        if(state.toString().equals("NIL"))
            state = eParseState.REQ;
        
        // Set the toParse string with the current line
        if(setParseString(parse)) {
            StringTokenizer tokenizedLine = new StringTokenizer(toParse);
            switch(state) {
                case REQ:
                    if(!toParse.equals(""))
                        result = processRequest(tokenizedLine);
                    else {
                        // Set state to complete in case of an error
                        // Also stop parsing
                        state = eParseState.COMPLETE;
                    }
                    break;
                case OPT:
                    if(!toParse.equals(""))
                        result = processOptions(tokenizedLine);
                    else {
                        if(request.equals(eParseRequest.GET))
                            state = eParseState.COMPLETE;
                        else
                            state = eParseState.PARM;
                        // Set result to false for both GET and POST
                        // requests. This is end of the header. We
                        // will read the body using a different API
                        //result = false;
                    }
                    break;
                case PARM:
                    if(!toParse.equals(""))
                        result = processParms(tokenizedLine);
                    else {
                        // Probably end of input, so stop parsing
                        state = eParseState.COMPLETE;
                    }
                    break;
                case COMPLETE:
                default:
                    state = eParseState.COMPLETE;
                    break;
            }
        }
        else {
            // Input String in null!!
            // Probably end of string
            state = eParseState.COMPLETE;
        }
        return result;
    }
    
    public boolean processRequest(StringTokenizer tkLine) {
        boolean result = false;
        int parm = 0;
        request = eParseRequest.fromString(tkLine.nextToken());
        if(!request.equals(eParseRequest.NIL)) {
            fileName = tkLine.nextToken();
            
            // If this is a GET request the file name may 
            // include some parameters as well
            if(request.equals(eParseRequest.GET)) {
                if((parm = fileName.indexOf("?")) > 0) {
                    request_parms = fileName.substring(parm+1);
                    fileName = fileName.substring(0, parm);
                }
            }
            
            // Change state to OPT.
            state = eParseState.OPT;
            result = true;
        }
        return result;
    }
    
    public boolean processOptions (StringTokenizer tkLine) {
        String temp = new String("");
        option = eParseOption.fromString(tkLine.nextToken());
        if (!option.equals(eParseOption.NIL)) {
            if ((temp = tkLine.nextToken()) != null)
                optVal[option.toInt()] = temp;
        }
        return true;
    }
    
    public boolean processParms(StringTokenizer tkLine) {
        if(!tkLine.equals("")) {
            // Currently only FORM URL ENCODED as the content type is supported
            if(optVal[eParseOption.CONTENT_TYPE.toInt()].equals("application/x-www-form-urlencoded"))
                request_parms = toParse;
            else
                request_parms = "";
        }
        // Set state to Complete anyways
        state = eParseState.COMPLETE;
        return false;
    }
    
    public String getParms() {
        String result = "";
        if(request_parms != null)
            result = request_parms;
        return result;
    }
    
    public String getFileName() {
        if(fileName != null)
            return fileName;
        else
            return "";
    }
}
